package com.dmcb.common.business.utils;

import com.dmcb.trade.business.entities.InputStreamCache;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 导出Excel文档工具类
 */
public class ExcelUtil {
    private final static String xls = "xls";
    private final static String xlsx = "xlsx";

    /**
     * 创建excel文档，
     *
     * @param list        数据
     * @param keys        list中map的key数组集合
     * @param columnNames excel的列名
     */
    public static Workbook WorkBook(List<Map<String, Object>> list, String[] keys, String columnNames[]) {
        // 创建excel工作簿
        SXSSFWorkbook wb = new SXSSFWorkbook();
        // 创建第一个sheet（页），并命名
        Sheet sheet = wb.createSheet(list.get(0).get("sheetName").toString());
        // 手动设置列宽。第一个参数表示要为第几列设；，第二个参数表示列的宽度，n为列高的像素数。
        for (int i = 0; i < keys.length; i++) {
            sheet.setColumnWidth(i, (35 * 130));
        }

        // 创建第一行
        Row row = sheet.createRow(0);

        // 创建两种单元格格式
        CellStyle cs = wb.createCellStyle();
        CellStyle cs2 = wb.createCellStyle();

        // 创建两种字体
        Font f = wb.createFont();
        Font f2 = wb.createFont();

        // 创建第一种字体样式（用于列名）
        f.setFontHeightInPoints((short) 10);
        f.setColor(IndexedColors.BLACK.getIndex());
        f.setBoldweight(Font.BOLDWEIGHT_BOLD);

        // 创建第二种字体样式（用于值）
        f2.setFontHeightInPoints((short) 10);
        f2.setColor(IndexedColors.BLACK.getIndex());

        // 设置第一种单元格的样式（用于列名）
        cs.setFont(f);
        cs.setBorderLeft(CellStyle.BORDER_THIN);
        cs.setBorderRight(CellStyle.BORDER_THIN);
        cs.setBorderTop(CellStyle.BORDER_THIN);
        cs.setBorderBottom(CellStyle.BORDER_THIN);
        cs.setAlignment(CellStyle.ALIGN_CENTER);

        // 设置第二种单元格的样式（用于值）
        cs2.setFont(f2);
        cs2.setBorderLeft(CellStyle.BORDER_THIN);
        cs2.setBorderRight(CellStyle.BORDER_THIN);
        cs2.setBorderTop(CellStyle.BORDER_THIN);
        cs2.setBorderBottom(CellStyle.BORDER_THIN);
        cs2.setAlignment(CellStyle.ALIGN_CENTER);
        //设置列名
        for (int i = 0; i < columnNames.length; i++) {
            Cell cell = row.createCell(i);
            cell.setCellValue(columnNames[i]);
            cell.setCellStyle(cs);
        }
        //设置每行每列的值
        for (int i = 1; i < list.size(); i++) {
            // Row 行,Cell 方格 , Row 和 Cell 都是从0开始计数的
            // 创建一行，在页sheet上
            Row row1 = sheet.createRow(i);
            // 在row行上创建一个方格
            for (int j = 0; j < keys.length; j++) {
                Cell cell = row1.createCell(j);
                if (list.get(i).get(keys[j]) != null) {
                    if (list.get(i).get(keys[j]).getClass().getName().equals("java.lang.Integer")) {
                        cell.setCellValue(Integer.parseInt(list.get(i).get(keys[j]).toString()));
                    } else {
                        cell.setCellValue(list.get(i).get(keys[j]).toString());
                    }
                } else {
                    cell.setCellValue(list.get(i).get(keys[j]) == null ? " " : list.get(i).get(keys[j]).toString());
                }
                cell.setCellStyle(cs2);
            }
        }
        return wb;
    }


    /**
     * 创建excel文档，
     *
     * @param list        数据
     * @param keys        list中map的key数组集合
     * @param columnNames excel的列名
     */
    public static Workbook createWorkBook(List<Map<String, Object>> list, String[] keys, String columnNames[], List<Map<String, Object>> lists, String[] keyss, String columnNamess[], int type) {
        // 创建excel工作簿
        SXSSFWorkbook wb = new SXSSFWorkbook();
        for (int a = 0; a < 2; a++) {
            if (a == 0) {
                Sheet sheet = wb.createSheet();
                if (type == 1) {
                    wb.setSheetName(a, "已提现维权文章");
                } else {
                    wb.setSheetName(a, "原创文章");
                }
                Header header = sheet.getHeader();
                header.setCenter("sheet");
//                // 创建第一个sheet（页），并命名
//                Sheet sheet = wb.createSheet(list.get(a).get("sheetName").toString());
                // 手动设置列宽。第一个参数表示要为第几列设；，第二个参数表示列的宽度，n为列高的像素数。
                for (int i = 0; i < keys.length; i++) {
                    sheet.setColumnWidth(i, (35 * 130));
                }
                // 创建第一行
                Row row = sheet.createRow(0);

                // 创建两种单元格格式
                CellStyle cs = wb.createCellStyle();
                CellStyle cs2 = wb.createCellStyle();
                CellStyle cs3 = wb.createCellStyle();

                // 创建两种字体
                Font f = wb.createFont();
                Font f2 = wb.createFont();

                // 创建第一种字体样式（用于列名）
                f.setFontHeightInPoints((short) 10);
                f.setColor(IndexedColors.BLACK.getIndex());
                f.setBoldweight(Font.BOLDWEIGHT_BOLD);
                f.setFontName("微软雅黑");

                // 创建第二种字体样式（用于值）
                f2.setFontHeightInPoints((short) 10);
                f2.setColor(IndexedColors.BLACK.getIndex());
                f2.setFontName("微软雅黑");

                // 设置第一种单元格的样式（用于列名）
                cs.setFont(f);
                cs.setBorderLeft(CellStyle.BORDER_THIN);
                cs.setBorderRight(CellStyle.BORDER_THIN);
                cs.setBorderTop(CellStyle.BORDER_THIN);
                cs.setBorderBottom(CellStyle.BORDER_THIN);
                cs.setAlignment(CellStyle.ALIGN_CENTER);

                // 设置第二种单元格的样式（用于值）
                cs2.setFont(f2);
                cs2.setBorderLeft(CellStyle.BORDER_THIN);
                cs2.setBorderRight(CellStyle.BORDER_THIN);
                cs2.setBorderTop(CellStyle.BORDER_THIN);
                cs2.setBorderBottom(CellStyle.BORDER_THIN);
                cs2.setAlignment(CellStyle.ALIGN_CENTER);


                cs3.setFillPattern(CellStyle.SOLID_FOREGROUND);
                cs3.setFillForegroundColor(IndexedColors.RED.getIndex());
                cs3.setFillBackgroundColor(IndexedColors.RED.getIndex());
                cs3.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 居中

                //设置列名
                for (int i = 0; i < columnNames.length; i++) {
                    Cell cell = row.createCell(i);
                    cell.setCellValue(columnNames[i]);
                    cell.setCellStyle(cs);
                }
                int size = list.size() + 1;
                //设置每行每列的值
                for (int i = 1; i < size; i++) {
                    // Row 行,Cell 方格 , Row 和 Cell 都是从0开始计数的
                    // 创建一行，在页sheet上
                    Row row1 = sheet.createRow(i);
                    if (i == list.size()) {
                        sheet.addMergedRegion(new CellRangeAddress(i, (short) 0, i, (short) 4));
                        Cell cell = row1.createCell(0);
                        cell.setCellValue("详细信息请看下页");
                        cell.setCellStyle(cs2);
                        cell.setCellStyle(cs3);
                    } else {
                        // 在row行上创建一个方格
                        for (int j = 0; j < keys.length; j++) {
                            Cell cell = row1.createCell(j);
                            if (list.get(i).get(keys[j]) != null) {
                                if (list.get(i).get(keys[j]).getClass().getName().equals("java.lang.Integer")) {
                                    cell.setCellValue(Integer.parseInt(list.get(i).get(keys[j]).toString()));
                                } else {
                                    cell.setCellValue(list.get(i).get(keys[j]).toString());
                                }
                            } else {
                                cell.setCellValue(list.get(i).get(keys[j]) == null ? " " : list.get(i).get(keys[j]).toString());
                            }

                            cell.setCellStyle(cs2);
                        }
                    }
                }

            } else {
                Sheet sheet = wb.createSheet();
                if (type == 1) {
                    wb.setSheetName(a, "已提现转载文章");
                } else {
                    wb.setSheetName(a, "原创文章及侵权文章");
                }
                Header header = sheet.getHeader();
                header.setCenter("sheet");

//                // 创建第一个sheet（页），并命名
//                Sheet sheet = wb.createSheet(lists.get(a).get("sheetName").toString());
                // 手动设置列宽。第一个参数表示要为第几列设；，第二个参数表示列的宽度，n为列高的像素数。
                for (int i = 0; i < keyss.length; i++) {
                    sheet.setColumnWidth(i, (35 * 130));
                }

                // 创建第一行
                Row row = sheet.createRow(0);

                // 创建两种单元格格式
                CellStyle cs = wb.createCellStyle();
                CellStyle cs2 = wb.createCellStyle();

                // 创建两种字体
                Font f = wb.createFont();
                Font f2 = wb.createFont();

                // 创建第一种字体样式（用于列名）
                f.setFontHeightInPoints((short) 10);
                f.setColor(IndexedColors.BLACK.getIndex());
                f.setBoldweight(Font.BOLDWEIGHT_BOLD);
                f.setFontName("微软雅黑");

                // 创建第二种字体样式（用于值）
                f2.setFontHeightInPoints((short) 10);
                f2.setColor(IndexedColors.BLACK.getIndex());
                f2.setFontName("微软雅黑");

                // 设置第一种单元格的样式（用于列名）
                cs.setFont(f);
                cs.setBorderLeft(CellStyle.BORDER_THIN);
                cs.setBorderRight(CellStyle.BORDER_THIN);
                cs.setBorderTop(CellStyle.BORDER_THIN);
                cs.setBorderBottom(CellStyle.BORDER_THIN);
                cs.setAlignment(CellStyle.ALIGN_CENTER);

                // 设置第二种单元格的样式（用于值）
                cs2.setFont(f2);
                cs2.setBorderLeft(CellStyle.BORDER_THIN);
                cs2.setBorderRight(CellStyle.BORDER_THIN);
                cs2.setBorderTop(CellStyle.BORDER_THIN);
                cs2.setBorderBottom(CellStyle.BORDER_THIN);
                cs2.setAlignment(CellStyle.ALIGN_CENTER);
                //设置列名
                for (int i = 0; i < columnNamess.length; i++) {
                    Cell cell = row.createCell(i);
                    cell.setCellValue(columnNamess[i]);
                    cell.setCellStyle(cs);
                }
                //设置每行每列的值
                for (int i = 1; i < lists.size(); i++) {
                    // Row 行,Cell 方格 , Row 和 Cell 都是从0开始计数的
                    // 创建一行，在页sheet上
                    Row row1 = sheet.createRow(i);
                    // 在row行上创建一个方格
                    for (int j = 0; j < keyss.length; j++) {
                        Cell cell = row1.createCell(j);
                        if (lists.get(i).get(keyss[j]) != null) {
                            if (lists.get(i).get(keyss[j]).getClass().getName().equals("java.lang.Integer")) {
                                cell.setCellValue(Integer.parseInt(lists.get(i).get(keyss[j]).toString()));
                            } else {
                                cell.setCellValue(lists.get(i).get(keyss[j]).toString());
                            }
                        } else {
                            cell.setCellValue(lists.get(i).get(keyss[j]) == null ? " " : lists.get(i).get(keyss[j]).toString());
                        }
                        cell.setCellStyle(cs2);
                    }
                }
            }
        }
        return wb;
    }

    public static Sheet getSheet(MultipartFile file, int page) throws IOException {
        Workbook wb;
        String name = file.getOriginalFilename();
        String fileType = name.substring(name.lastIndexOf(".") + 1, name.length());
        InputStream is;
        switch (fileType) {
            case "xls":
                is = file.getInputStream();
                InputStreamCache cache = new InputStreamCache(is);
                is = cache.getInputStream();
                POIFSFileSystem fs = new POIFSFileSystem(is);
                wb = new HSSFWorkbook(fs);
                break;
            case "xlsx":
                is = file.getInputStream();
                wb = new XSSFWorkbook(is);
                break;
            default:
                return null;
        }

        return wb.getSheetAt(page);
    }

    public static List<String> getExcelDataList(MultipartFile file, int page, int line) {
        List<String> list = new ArrayList<>();
        try {

            Sheet sheet = ExcelUtil.getSheet(file, page);
            if (sheet == null) {
                return null;
            }
            int rowLens = sheet.getLastRowNum();
            String content;
            Row row;
            Cell cell;
            for (int rowCount = 1; rowCount <= rowLens; rowCount++) {
                System.out.println("读取行：" + rowCount);
                row = sheet.getRow(rowCount);
                if (row != null) {
                    cell = row.getCell(line);
                    content = cell.getStringCellValue().trim();
                    if (StringUtils.isBlank(content)) {
                        break;
                    } else {
                        list.add(content.trim());
                    }
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }


    /**
     * 读入excel文件，解析后返回
     * @param file
     * @throws IOException
     */
    public static List<String[]> readExcel(File file) throws IOException{
        //检查文件
        String name = file.getName();
        //获得Workbook工作薄对象
        Workbook workbook = getWorkBook(file);
        //创建返回对象，把每行中的值作为一个数组，所有行作为一个集合返回
        List<String[]> list = new ArrayList<String[]>();
        if(workbook != null){
            for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){
                //获得当前sheet工作表
                Sheet sheet = workbook.getSheetAt(sheetNum);
                if(sheet == null){
                    continue;
                }
                //获得当前sheet的开始行
                int firstRowNum  = sheet.getFirstRowNum();
                //获得当前sheet的结束行
                int lastRowNum = sheet.getLastRowNum();
                //循环除了第一行的所有行
                for(int rowNum = firstRowNum+1;rowNum <= lastRowNum;rowNum++){
                    //获得当前行
                    Row row = sheet.getRow(rowNum);
                    if(row == null){
                        continue;
                    }
                    //获得当前行的开始列
                    int firstCellNum = row.getFirstCellNum();
                    //获得当前行的列数
                    int lastCellNum = row.getPhysicalNumberOfCells();
                    String[] cells = new String[row.getPhysicalNumberOfCells()];
                    //循环当前行
                    for(int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++){
                        Cell cell = row.getCell(cellNum);
                        cells[cellNum] = getCellValue(cell);
                    }
                    list.add(cells);
                }
            }
            workbook.close();
        }
        return list;
    }
    public static void checkFile(File file) throws IOException{
        //判断文件是否存在
        if(null == file){
            throw new FileNotFoundException("文件不存在！");
        }
        //获得文件名
        String fileName = file.getName();
        //判断文件是否是excel文件
        if(!fileName.endsWith(xls) && !fileName.endsWith(xlsx)){
            throw new IOException(fileName + "不是excel文件");
        }
    }
    public static Workbook getWorkBook(File file) {
        //获得文件名
        String fileName = file.getName();
        //创建Workbook工作薄对象，表示整个excel
        Workbook workbook = null;
        InputStream inputStream = null;
        try {
            //获取excel文件的io流
            inputStream = new FileInputStream(file);
            //根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
            if(fileName.endsWith(xls)){
                //2003
                workbook = new HSSFWorkbook(inputStream);
            }else if(fileName.endsWith(xlsx)){
                //2007
                workbook = new XSSFWorkbook(inputStream);
            }
        } catch (IOException e) {
          e.printStackTrace();
        }
        return workbook;
    }
    public static String getCellValue(Cell cell){
        String cellValue = "";
        if(cell == null){
            return cellValue;
        }
        //把数字当成String来读，避免出现1读成1.0的情况
        if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
            cell.setCellType(Cell.CELL_TYPE_STRING);
        }
        //判断数据的类型
        switch (cell.getCellType()){
            case Cell.CELL_TYPE_NUMERIC: //数字
                cellValue = String.valueOf(cell.getNumericCellValue());
                break;
            case Cell.CELL_TYPE_STRING: //字符串
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case Cell.CELL_TYPE_BOOLEAN: //Boolean
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_FORMULA: //公式
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            case Cell.CELL_TYPE_BLANK: //空值
                cellValue = "";
                break;
            case Cell.CELL_TYPE_ERROR: //故障
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue;
    }


}